/*
 * threadlib.h
 *
 *  Created on: 05.03.2012
 *      Author: caffeine
 */

#ifndef THREADLIB_H_
#define THREADLIB_H_

#include <lampe/config.h>

#ifdef WINDOWS_PLATFORM
#include <windows.h>
#include <winbase.h>
#endif

#ifdef POSIX_LIBLARY
#include <pthread.h>
#include <unistd.h>
#endif

#ifdef WINDOWS_PLATFORM
struct ThreadHeader{
	HANDLE Header;
	DWORD Id;
	ThreadHeader(){
		Header=0;
		Id=0;
	}
	ThreadHeader(int a){
		Header=(HANDLE)a;
		Id=(DWORD)a;
	}
};
//typedef DWORD WINAPI(*threadFunction)(LPVOID);
#define threadFunction LPTHREAD_START_ROUTINE
#define thread_function(name,arg) DWORD WINAPI name(LPVOID arg)

#define thread_static_function_of_class(classname,name,arg) DWORD WINAPI classname::name(LPVOID arg)
#endif

#ifdef POSIX_LIBLARY
#define ThreadHeader pthread_t
typedef void*(*threadFunction)(void *);
#define thread_function(name,arg) void*name(void*arg)
#define thread_static_function_of_class(classname,name,arg) void*classname::name(void*arg)
#endif


#ifdef POSIX_LIBLARY
bool thread_create(ThreadHeader*th,threadFunction fun,void*arg);
#endif

#ifdef WINDOWS_PLATFORM
bool thread_create(ThreadHeader*th,threadFunction fun,void*arg);
#endif

#ifdef POSIX_LIBLARY
#define MUTEX pthread_mutex_t
#endif

#ifdef POSIX_LIBLARY
#define CreateMutex(mutex) mutex=PTHREAD_MUTEX_INITIALIZER;
#endif

#ifdef POSIX_LIBLARY
#define DestryMutex(mutex)
#endif

#ifdef POSIX_LIBLARY
#define LOCK_MUTEX(mutex) pthread_mutex_lock(&mutex)
#endif

#ifdef POSIX_LIBLARY
#define UNLOCK_MUTEX(mutex) pthread_mutex_unlock(&mutex)
#endif

#ifdef POSIX_LIBLARY
#define WAIT_MUTEX(mutex) pthread_cond_wait(mutex)
#endif
/*
#ifdef WINDOWS_PLATFORM
#error Create CreateMutex, MUTEX,LOCK_MUTEX,UNLOCK_MUTEX,WAIT_MUTEX for Windows
#endif
*/
#ifdef POSIX_LIBLARY
#define thread_isthis(th) (pthread_equal(th,pthread_self()))
#endif
#ifdef WINDOWS_PLATFORM
#define thread_isthis(th) (GetCurrentThread()==th.Header)
#endif

#ifdef POSIX_LIBLARY
#define thread_join(th) pthread_join(th,0)
#endif

#ifdef WINDOWS_PLATFORM
#define thread_join(th) WaitForSingleObjectEx(th.Header,INFINITE,false)
#endif

#ifdef POSIX_LIBLARY
#define thread_sleep(ms) usleep(ms*1000)
#endif

#ifdef WINDOWS_PLATFORM
#define thread_sleep(ms) Sleep(ms)
#endif

#ifdef POSIX_LIBLARY
#define thread_stop(th) pthread_cancel(th);th=0
#endif

#ifdef WINDOWS_PLATFORM
#define thread_stop(th) TerminateThread(th.Header,0);CloseHandle(th.Header);th.Header=0;th.Id=0
#endif

/*
#ifdef WINDOWS_PLATFORM
#define thread_pause(th) SuspendThread(th.Header);
#endif

#ifdef WINDOWS_PLATFORM
#define thread_resume(th) ResumeThread(th.Header);
#endif

#ifdef POSIX_LIBLARY
	#error unsupport in LINUX
#endif

#ifdef POSIX_LIBLARY
	#error unsupport in LINUX
#endif
*/
#ifdef POSIX_LIBLARY
#define thread_clear(th) th=0
#endif

#ifdef WINDOWS_PLATFORM
#define thread_clear(th) th.Header=0;th.Id=0
#endif

#ifdef POSIX_LIBLARY
#define thread_isrunning(th) (th!=0)
#endif

#ifdef WINDOWS_PLATFORM
#define thread_isrunning(th) (th.Header!=0 && th.Id!=0)
#endif

#ifdef POSIX_LIBLARY
#define thread_exit() pthread_exit(0);
#endif

#ifdef WINDOWS_PLATFORM
#define thread_exit() ExitThread(GetCurrentThreadId());
#endif


#ifdef POSIX_LIBLARY
#define current_thread() pthread_self()
#endif

#ifdef WINDOWS_PLATFORM
#define current_thread() GetCurrentThreadId()
#endif

#endif /* THREADLIB_H_ */
